using System;
using System.Collections.Generic;
using System.Text;
using TTDotNet.Util;
using Microsoft.DirectX;
using System.Drawing;

namespace TTDotNet.Engine.Networks
{
    public enum RoadPathType { Road, Tunnel, Bridge }

    public class RoadPath
    {
        private RoadNode source;
        private RoadPathType type;
        private RoadNode destination;
        private int roadLength;
        private List<Vector3> pathSteps;
        private bool alongX = true;

        public RoadPath(RoadNode src, RoadPathType type, RoadNode dest, List<Vector3> path) 
        {
            this.type = type;
            this.source = src;
            this.destination = dest;
            this.roadLength = src.Coordinate.StraightLineDistanceTo(dest.Coordinate);
            this.pathSteps = path;

            if (source.Coordinate.X == destination.Coordinate.X)
                alongX = false;
        }

        public List<Vector3> PathSteps
        {
            get { return pathSteps; }
        }

        public RoadNode Source
        {
            get { return source; }
        }

        public RoadNode Destination
        {
            get { return destination; }
        }

        public RoadPathType RoadPathType
        {
            get { return type; }
        }

        public void SetDest(RoadNode node)
        {
            destination = node;
            roadLength = source.Coordinate.GridDistanceTo(node.Coordinate);
        }

        public int GetPathLength()
        {
            return roadLength;
        }

        public override string ToString()
        {
            return "Path runs from " + source.Coordinate + " to " + destination.Coordinate + " , a distance of " + roadLength + " tiles!";
        }

        //Must be a far better way of doing this.
        public static bool IsBetween(DDDCoordinate start, DDDCoordinate finish, DDDCoordinate coord)
        {
            Vector3 vstart = new Vector3(start.X, start.Y, start.Z);
            Vector3 vfinish = new Vector3(finish.X, finish.Y, finish.Z);
            Vector3 between = new Vector3(coord.X, coord.Y, coord.Z);

            Vector3 aToBgrad = Vector3.Normalize(Vector3.Subtract(between, vstart));
            Vector3 aToCgrad = Vector3.Normalize(Vector3.Subtract(vfinish, vstart));

            if ((coord.X - start.X) * (coord.X - finish.X) <= 0)
            {
                //if ((coord.Y - start.Y) * (coord.Y - finish.Y) <= 0)
                //{
                    if ((coord.Z - start.Z) * (coord.Z - finish.Z) <= 0)
                    {
                        return true;
                    }
                    return false;
                //}
                //return false;
            }
            return false;
        }

        public float GetPathHeightAt(float x, float z)
        {
            if (alongX)
            {
                for (int i = 0; i < pathSteps.Count - 1; i++)
                {
                    if (x >= pathSteps[i].X && x <= pathSteps[i + 1].X || x <= pathSteps[i].X && x >= pathSteps[i + 1].X)
                    {
                        float fractionAlong = (x - pathSteps[i].X) / (Math.Abs(pathSteps[i].X - pathSteps[i + 1].X));
                        return pathSteps[i].Y + (Math.Abs(fractionAlong) * (pathSteps[i + 1].Y - pathSteps[i].Y));
                    }
                }
            }
            else
            {
                for (int i = 0; i < pathSteps.Count - 1; i++)
                {
                    if (z >= pathSteps[i].Z && z <= pathSteps[i + 1].Z || z <= pathSteps[i].Z && z >= pathSteps[i + 1].Z)
                    {
                        float fractionAlong = (z - pathSteps[i].Z) / (Math.Abs(pathSteps[i].Z - pathSteps[i + 1].Z));
                        return pathSteps[i].Y + (Math.Abs(fractionAlong) * (pathSteps[i + 1].Y - pathSteps[i].Y));
                    }
                }
            }

            return -1;
        }

    }
}
